<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>秒表计时器</title>
  <style>
    .container {
      width: 600px;
      margin: 200px auto 0;
      text-align: center;
    }

    #showTime {
      font-size: 100px;
    }

    #startBtn,
    #resetBtn {
      width: 100px;
      height: 50px;
      font-size: 18px;
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div class="container">
    <div id="showTime">00:00:00</div>
    <button id="startBtn">开始</button>
    <button id="resetBtn">重置</button>
  </div>
  <script>
    let firstClickTime; // 记录首次点击开始按钮的时间戳 -
    let pauseDate; // 记录每次点击暂停按钮的时间戳
    let totalPauseTime = 0; // 累计暂停时间
    let flag = false; // 开关：控制开始与暂停状态的切换

    init();
    // 初始化：获取元素、绑定点击事件、开启定时器
    function init() {
      const showTime = document.getElementById("showTime");
      const startBtn = document.getElementById("startBtn");
      const resetBtn = document.getElementById("resetBtn");
      startBtn.addEventListener("click", clickHandler);
      resetBtn.addEventListener("click", clickHandler);
      setInterval(timeRefresh, 60); // 注意：定时器会一直处于开启状态中
    }

    // 1970/1/1 --> 首次开启 --(计时段1)-> 首次暂停 --(暂停时间1)-> 二次开启 --(计时段2)-> 二次暂停 --(暂停时间2)-> 三次开启 --(计时段3)-> Now
    // 结论：已经计时的时间 = 当前时间 - 首次开启时间 - 累计暂停时间

    // 时间刷新函数
    function timeRefresh() {
      // 只有当flag为true时，也就是刚点击完开始按钮，处于正在计时的状态中，才会执行后续代码
      if (!flag) return;
      // 当前时间 - 首次开启时间 - 累计暂停时间
      let times = new Date().getTime() - firstClickTime - totalPauseTime; // 已经计时的时间
      let minutes = Math.floor(times / 1000 / 60); // 毫秒转化为分钟
      let seconds = Math.floor(times / 1000 % 60); // 毫秒转化为秒钟
      let ms = Math.floor((times % 1000) / 10); // 毫秒保留前两位数
      // 动态刷新时间
      showTime.innerHTML = `${minutes<10?'0'+minutes:minutes}:${seconds<10?'0'+seconds:seconds}:${ms<10?'0'+ms:ms}`;
    }

    // 点击事件函数
    function clickHandler() {
      // 开始/暂停 按钮
      if (this === startBtn) {
        flag = !flag;

        // 当按钮内容为开始，点击后执行 (flag === true)
        if (flag) {
          this.innerHTML = "暂停";
          // console.log(pauseDate);
          // 如果上一次 点击暂停按钮的时间戳 是 undefined，表示还没有暂停过，直接返回0
          // 如果上一次 点击暂停按钮的时间戳 是 有值的，用当前毫秒数（即点击开始按钮的时间戳）减去 上一次点击暂停按钮的毫秒数，得到暂停时间
          totalPauseTime += !pauseDate ? 0 : new Date().getTime() - pauseDate; // 暂停时间可能为多次，进行累加

          // firstClickTime 一开始只声明过没有赋值，为undefined。经过第一次赋值操作之后，后续代码不再运行了
          if (firstClickTime) return; // return 要放在赋值操作之前，为了保证 firstClickTime 是唯一不变的，只会执行一次赋值操作
          firstClickTime = new Date().getTime(); // 记录首次点击开始按钮的时间戳
          // console.log(firstClickTime); // 只会打印一次

          return; // 为flag判断跳出
        }

        // 当按钮内容为暂停，点击后执行 (flag === false)
        this.innerHTML = "开始";
        pauseDate = new Date().getTime(); // 记录每次点击暂停按钮的时间戳

        // 注意：
        // 在函数体内，当省略了 else 语句时，需要在最后加上 return 来终止后续代码的运行。if else 二者取其一
        // return 函数的返回值，需要放在函数体内使用。不可以单独与 if, for...循环分支结构联用！
        return; // 为this是否等于startBtn判断跳出
      }

      // 重置按钮功能实现 (this !== startBtn)
      // 变量赋值为 null 和 0 和 '' 的区别？
      totalPauseTime = null; // null 可以清空变量内存
      pauseDate = null;
      firstClickTime = null;
      flag = false;
      startBtn.innerHTML = "开始";
      showTime.innerHTML = "00:00:00";
    }
  </script>
</body>

</html>